// 1.创建 Promise 构造函数
function Promise(callback){ //参数：执行器函数
    let self = this;

    // 2.2声明一个数组，用来保存成功和失败的回调
    this.arrs = []


    // 6.设置promise实例对象的默认状态
    this.PromiseState = 'pending'
    // 6.设置promise实例对象的默认结果值
    this.PromiseResult = undefined;

    // 4.声明 resolve 函数
    function resolve(value){
        // 3.1判断实例对象的状态是否修改过，如果修改过，没有必要执行了
        if(self.PromiseState !== 'pending') return;

        // 5.修改promise实例对象的状态
        self.PromiseState = 'fulfilled'
        // 5.修改peomise实例对象的结果值
        self.PromiseResult = value;

        // 2.4一旦执行成功的状态，我们就把保存的成功回调函数取出来执行
        // this.arrs = [{}]
        // item 是数组中的每一个元素  {}
        self.arrs.forEach(item =>{
            item.abc(value)
        })
    
    }
    // 4.声明 reject 函数
    function reject(reason){
        // 3.1判断实例对象的状态是否修改过，如果修改过，没有必要执行了
        if(self.PromiseState !== 'pending') return;
        
        // 5.修改promise实例对象的状态
        self.PromiseState = 'rejected'
        // 5.修改peomise实例对象的结果值
        self.PromiseResult = reason;
        // 2.5一旦执行失败的状态，我们就把保存的失败回调函数取出来执行
        self.arrs.forEach(item =>{
            item.onRejected(reason)
        })
    }
    // 3.调用执行器函数
    callback(resolve,reject);
}
// 2.添加then方法
Promise.prototype.then = function(onResolved,onRejected){
    setTimeout(()=>{
        // 6.2判断 onRejected 是不是函数
        // 如果不是，需要给他补一个腿 
        // 如果是，就不用管了
        if(typeof onRejected !== 'function'){
            // 需要设置一个默认值
            onRejected = reason => {
              throw reason;
            }
        }
        // 7.1值传递：判断 onResolved 是不是函数
        // 如果不是，需要给他补一个腿
        if(typeof onResolved !== 'function'){
            onResolved = value =>{
                return value;
            }
        }

        // 4.1 p.then()方法的返回值是新的promise实例对象
        return new Promise((resolve,reject)=>{
            // 7.根据修改后的状态，调用相关的函数
            // 成功
            if(this.PromiseState === 'fulfilled'){
                try{

                    // 新的promise对象的状态和结果值，取决于onResolved函数的返回值
                    // 4.2 保存onResolved函数的返回值
                    let res = onResolved(this.PromiseResult)
                    // 4.3判断 res 是不是promise的实例对象          
                    if(res instanceof Promise){
                        // 一个promise实例对象是成功还是失败
                        // 我们只要根据p.then()方法，看一下他哪一个回调函数执行就可以了
                        // 如果是
                        res.then(v=>{
                            // 成功
                            resolve(v);
                        },r=>{
                            // 失败
                            reject(r);
                        })
                    }else{
                        // 如果不是，状态成功，结果值就是return写的东西
                        resolve(res);
                    }

                }catch(e){
                    reject(e)
                }

            }
            // 失败
            if(this.PromiseState === 'rejected'){
                try{
                    // 4.2 保存onRejected函数的返回值
                    let res = onRejected(this.PromiseResult)
                    // 4.3判断 res 是不是promise的实例对象      
                    if(res instanceof Promise){
                        res.then(v=>{
                            resolve(v)
                        },r=>{
                            reject(r)
                        })
                    }else{
                        resolve(res)
                    }
                }catch(e){
                    reject(e)
                }

            }
            // 2.1创建pending状态
            if(this.PromiseState === 'pending'){
                // 时间一到，到底执行成功还是失败我们是不清楚的
                // 所以，我们需要把成功和失败的回调函数暂时保存起来（数组）
                // 2.3把成功和失败的回调函数存到数组中
                this.arrs.push({
                    abc : function(value){
                        try{
                            let res = onResolved(value)
                            if(res instanceof Promise){
                                res.then(v=>{
                                    resolve(v)
                                },r=>{
                                    reject(r)
                                })
                            }else{
                                resolve(res);
                            }
                        }catch(e){
                            reject(e)
                        }
                    },
                    onRejected :function(reason){
                        try{
                            let res = onRejected(reason)
                            if(res instanceof Promise){
                                res.then(v=>{
                                    resolve(v)
                                },r=>{
                                    reject(r)
                                })
                            }else{
                                resolve(res);
                            }
                        }catch(e){
                            reject(e)
                        }
                    }
                })
                
                // 一旦执行失败的状态，我们就把保存的失败回调函数取出来执行
                
            }
            
        })
    })
    
};

// 6.1添加 catch方法
Promise.prototype.catch = function(onRejected){
    return this.then(undefined,onRejected)
}